package com.sdkj.fixed.asset.hc.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.sdkj.fixed.asset.api.assets.in_vo.BorrowIssueExtend;
import com.sdkj.fixed.asset.api.hc.vo.in.IdParams;
import com.sdkj.fixed.asset.api.hc.vo.in.ReceiptMoveGetPageParams;
import com.sdkj.fixed.asset.api.hc.vo.in.ReceiptSetGetPageParams;
import com.sdkj.fixed.asset.api.hc.vo.out.*;
import com.sdkj.fixed.asset.common.base.BaseMapper;
import com.sdkj.fixed.asset.common.base.BaseService;
import com.sdkj.fixed.asset.common.base.PageParams;
import com.sdkj.fixed.asset.common.exception.LogicException;
import com.sdkj.fixed.asset.common.utils.TimeTool;
import com.sdkj.fixed.asset.hc.mapper.*;
import com.sdkj.fixed.asset.pojo.hc.*;
import com.sdkj.fixed.asset.pojo.system.UserDateAuth;
import com.sdkj.fixed.asset.pojo.system.UserManagement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.persistence.Transient;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/***
 *
 * @author scx
 *
 */
@Service
public class ReceiptMoveService extends BaseService<ReceiptMove> {

    private static Logger log = LoggerFactory.getLogger(ReceiptMoveService.class);

    @Resource
    private ReceiptMoveMapper mapper;

    @Resource
    private ReceiptMoveProductMapper receiptMoveProductMapper;

    @Resource
    private UserManagementMapper userManagementMapper;

    @Resource
    private UserDataAuthMapper userDataAuthMapper;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private CategoryProductMapper categoryProductMapper;

    @Override
    public BaseMapper<ReceiptMove> getMapper() {
        return mapper;
    }

    @Resource
    private QwertMapper qwertMapper;

    private void qwertyu(CategoryProduct categoryProduct, ReceiptMoveProduct receiptMoveProduct, Boolean flag) {
        if (categoryProduct.getProductNum() == null) {
            categoryProduct.setTotalPrice("0.00");
            categoryProduct.setProductNum(0);
            categoryProduct.setPrice("0.00");
        }
        Integer totalNum = 0;
        Float totalPrice;
        Qwert qwert = new Qwert();
        if (flag) {
            totalNum = categoryProduct.getProductNum() + receiptMoveProduct.getNum();
            totalPrice = Float.parseFloat(receiptMoveProduct.getTotalPrice()) +
                    Float.parseFloat(categoryProduct.getTotalPrice());
            qwert.setCategoryId(mapper.selectByPrimaryKey(receiptMoveProduct.getReceiptId()).getInCategory());
        } else {
            totalNum = categoryProduct.getProductNum() - receiptMoveProduct.getNum();
            totalPrice = Float.parseFloat(categoryProduct.getTotalPrice()) - Float.parseFloat(receiptMoveProduct.getTotalPrice());
            qwert.setCategoryId1(mapper.selectByPrimaryKey(receiptMoveProduct.getReceiptId()).getOutCategory());
        }

        DecimalFormat df = new DecimalFormat("0.00");//设置保留位数
        String format = "";
        if (totalNum == 0) {
            format = "0.00";
        } else {
            format = df.format((float) totalPrice / totalNum);
        }
        qwert.setBussinessDate(mapper.selectByPrimaryKey(receiptMoveProduct.getReceiptId()).getBussinessDate());


        qwert.setBeforeNum(categoryProduct.getProductNum());
        qwert.setBeforePrice(df.format(Float.parseFloat(categoryProduct.getPrice())));
        qwert.setBeforeTotalPrice(df.format(Float.parseFloat(categoryProduct.getTotalPrice())));
        qwert.setNumber(receiptMoveProduct.getNumber());
        qwert.setCtime(DateUtil.now());
        qwert.setCuser(receiptMoveProduct.getCuser());
        qwert.setProductId(receiptMoveProduct.getProductId());
        qwert.setNum(receiptMoveProduct.getNum());
        qwert.setPrice(receiptMoveProduct.getPrice());
        qwert.setTotalPrice(receiptMoveProduct.getTotalPrice());
        qwert.setAfterNum(totalNum);
        qwert.setAfterPrice(format);
        qwert.setAfterTotalPrice(df.format(totalPrice));
        qwertMapper.insertSelective(qwert);
    }

    /**
     * 减库存
     *
     * @param categoryProduct    仓库物品关联
     * @param receiptMoveProduct 订单物品关联
     * @throws Exception
     */
    private synchronized void minusNum(CategoryProduct categoryProduct, ReceiptMoveProduct receiptMoveProduct) throws NumberFormatException {
        //计算总库存
        Integer totalNum = categoryProduct.getProductNum() - receiptMoveProduct.getNum();
        if (totalNum < 0) {
            throw new LogicException("库存不足");
        }
        categoryProduct.setProductNum(totalNum);
        //计算出库后物品总价
        Float totalPrice = Float.parseFloat(categoryProduct.getPrice()) * totalNum;
//        Float totalPrice = Float.parseFloat(receiptMoveProduct.getTotalPrice()) -
//                Float.parseFloat(categoryProduct.getTotalPrice());
        //计算出库后物品单价
        DecimalFormat df = new DecimalFormat("0.00");//设置保留位数
        String format = "";
        if (totalNum == 0) {
            Product product = productMapper.selectByPrimaryKey(receiptMoveProduct.getProductId());
            if (StrUtil.isNotBlank(product.getPrice())) {
                format = product.getPrice();
            } else {
                format = "0";
            }
        } else {
            format = df.format((float) totalPrice / totalNum);
        }
        categoryProduct.setTotalPrice(df.format(totalPrice));
        categoryProduct.setPrice(format);
        categoryProductMapper.updateByPrimaryKey(categoryProduct);
    }

    /**
     * 加库存
     *
     * @param categoryProduct    仓库物品关联
     * @param receiptMoveProduct 订单物品关联
     * @throws Exception
     */
    private synchronized void addNum(CategoryProduct categoryProduct, ReceiptMoveProduct receiptMoveProduct) throws NumberFormatException {
        //计算总库存
        Integer totalNum = categoryProduct.getProductNum() + receiptMoveProduct.getNum();
        categoryProduct.setProductNum(totalNum);
        //计算入库后物品总价
        Float totalPrice = Float.parseFloat(receiptMoveProduct.getTotalPrice()) +
                Float.parseFloat(categoryProduct.getTotalPrice());
        categoryProduct.setTotalPrice(String.valueOf(totalPrice));
        //计算入库后物品单价
        DecimalFormat df = new DecimalFormat("0.00");//设置保留位数
        String format = "";
        if (totalNum == 0) {
            format = "0";
        } else {
            format = df.format((float) totalPrice / totalNum);
        }
        categoryProduct.setPrice(format);
        categoryProductMapper.updateByPrimaryKeySelective(categoryProduct);
    }

    /**
     * 新增
     *
     * @param entity
     * @return
     */
    @Transactional
    public ReceiptMove add(ReceiptMove entity) {
        if (entity.getInCategory().equals(entity.getOutCategory())) {
            throw new LogicException("调入仓库和调出仓库不可一致");
        }
        if (categoryMapper.selectByPrimaryKey(entity.getInCategory()).getIsCheck() == 1) {
            throw new LogicException("调入仓库在盘点中");
        }
        if (categoryMapper.selectByPrimaryKey(entity.getOutCategory()).getIsCheck() == 1) {
            throw new LogicException("调出仓库在盘点中");
        }
        entity.setNumber("DB" + TimeTool.getTimeDate14());
        mapper.insertSelective(entity);
        List<ReceiptMoveProduct> receiptMoveProductList = entity.getReceiptMoveProductList();
        for (ReceiptMoveProduct receiptMoveProduct : receiptMoveProductList) {
            if (receiptMoveProduct.getPrice().length() > 32) {
                throw new LogicException("单价超出最大长度32位");
            }
            if (receiptMoveProduct.getTotalPrice().length() > 32) {
                throw new LogicException("总价超出最大长度32位");
            }
            receiptMoveProduct.setReceiptId(entity.getId());
            receiptMoveProductMapper.insertSelective(receiptMoveProduct);
            //出库方
            //新增不变库存
            Example exampleIn = new Example(CategoryProduct.class);
            Example.Criteria criteriaIn = exampleIn.createCriteria();
            criteriaIn.andEqualTo("categoryId", entity.getOutCategory());
            criteriaIn.andEqualTo("productId", receiptMoveProduct.getProductId());
            List<CategoryProduct> categoryProductsIn = categoryProductMapper.selectByExample(exampleIn);
            DecimalFormat df = new DecimalFormat("0.00");//设置保留位数
            for (CategoryProduct categoryProduct : categoryProductsIn) {
                receiptMoveProduct.setPrice(categoryProduct.getPrice());
                Float totalPrice = Float.parseFloat(categoryProduct.getPrice()) * receiptMoveProduct.getNum();
                receiptMoveProduct.setTotalPrice(df.format(totalPrice));
                receiptMoveProductMapper.updateByPrimaryKeySelective(receiptMoveProduct);
                if (categoryProduct.getProductNum() < receiptMoveProduct.getNum()) {
                    throw new LogicException("库存不足");
                }
            }
            //入库方
            //新增不变库存
//            Example exampleOut = new Example(CategoryProduct.class);
//            Example.Criteria criteriaOut = exampleOut.createCriteria();
//            criteriaOut.andEqualTo("categoryId", entity.getOutCategory());
//            criteriaOut.andEqualTo("productId", receiptMoveProduct.getProductId());
//            List<CategoryProduct> categoryProductsOut = categoryProductMapper.selectByExample(exampleOut);
//            for (CategoryProduct categoryProduct : categoryProductsOut) {
//                addNum(categoryProduct, receiptMoveProduct);
//            }
        }
        return entity;
    }

    /**
     * 修改
     *
     * @param entity
     * @param flag
     * @return
     */
    @Transactional
    public ReceiptMove edit(ReceiptMove entity, Boolean flag) {
        UserManagement user = userManagementMapper.selectByPrimaryKey(entity.getUserId());
        if (user.getDataIsAll() == 2) {
            Example examples = new Example(UserDateAuth.class);
            Example.Criteria criterias = examples.createCriteria();
            criterias.andEqualTo("type", 4);
            criterias.andEqualTo("userId", entity.getUserId());
            List<UserDateAuth> userDateAuths = userDataAuthMapper.selectByExample(examples);
            Boolean validate = false;
            for (UserDateAuth userDateAuth : userDateAuths) {
                if (userDateAuth.getAuthId().equals(entity.getInCategory())) {
                    validate = true;
                }
            }
            if (!validate) {
                throw new LogicException("调入仓库不可用");
            }
            Boolean validate1 = false;
            for (UserDateAuth userDateAuth : userDateAuths) {
                if (userDateAuth.getAuthId().equals(entity.getOutCategory())) {
                    validate1 = true;
                }
            }
            if (!validate1) {
                throw new LogicException("调出仓库不可用");
            }
        }
        if (entity.getInCategory().equals(entity.getOutCategory())) {
            throw new LogicException("调入仓库和调出仓库不可一致");
        }
        if (categoryMapper.selectByPrimaryKey(entity.getInCategory()).getIsCheck() == 1) {
            throw new LogicException("调入仓库在盘点中");
        }
        if (categoryMapper.selectByPrimaryKey(entity.getOutCategory()).getIsCheck() == 1) {
            throw new LogicException("调出仓库在盘点中");
        }
        if (categoryMapper.selectByPrimaryKey(entity.getInCategory()).getState() != 1) {
            throw new LogicException("调入仓库不可用");
        }
        if (categoryMapper.selectByPrimaryKey(entity.getOutCategory()).getState() != 1) {
            throw new LogicException("调出仓库不可用");
        }
        ReceiptMove receiptMove = mapper.selectByPrimaryKey(entity.getId());
        if (receiptMove.getConfirm() == 1) {
            throw new LogicException("已完成，不能编辑");
        }
        Example example = new Example(ReceiptMoveProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("receiptId", receiptMove.getId());
        //库存表改数
        List<ReceiptMoveProduct> receiptMoveProductList = receiptMoveProductMapper.selectByExample(example);
        for (ReceiptMoveProduct receiptMoveProduct : receiptMoveProductList) {
            receiptMoveProductMapper.delete(receiptMoveProduct);
        }
        while (flag) {
            mapper.updateByPrimaryKey(entity);
            return entity;
        }
        mapper.deleteByPrimaryKey(entity.getId());
        entity.setState(1);
        entity.setConfirm(2);
        add(entity);
        return entity;
    }

    /**
     * 删除
     *
     * @param entity
     * @return
     */
    @Transactional
    public ReceiptMove del(IdParams entity) {
        ReceiptMove receiptMove = mapper.selectByPrimaryKey(entity.getId());
        if (receiptMove.getConfirm() == 1) {
            throw new LogicException("已完成，不能删除");
        }
        receiptMove.setState(2);
        receiptMove.setUserId(entity.getEuser());
        edit(receiptMove, true);
        return receiptMove;
    }

    /**
     * 确认
     *
     * @param entity
     * @return
     */
    @Transactional
    public ReceiptMove confirm(ReceiptMove entity) {
        ReceiptMove receiptMove = mapper.selectByPrimaryKey(entity.getId());
        if (categoryMapper.selectByPrimaryKey(receiptMove.getInCategory()).getIsCheck() == 1) {
            throw new LogicException("调入仓库在盘点中");
        }
        if (categoryMapper.selectByPrimaryKey(receiptMove.getOutCategory()).getIsCheck() == 1) {
            throw new LogicException("调出仓库在盘点中");
        }
        if (receiptMove.getConfirm() == 1) {
            throw new LogicException("已完成的不能再次确认");
        }
        receiptMove.setConfirm(1);
        receiptMove.setConfirmBussinessDate(DateUtil.now());
        receiptMove.setConfirmTime(DateUtil.now());
        receiptMove.setConfirmComment(entity.getConfirmComment());
        receiptMove.setConfirmUser(entity.getConfirmUser());
        mapper.updateByPrimaryKeySelective(receiptMove);
        Example example = new Example(ReceiptMoveProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("receiptId", receiptMove.getId());
        //库存表改数
        List<ReceiptMoveProduct> receiptMoveProductList = receiptMoveProductMapper.selectByExample(example);
        for (ReceiptMoveProduct receiptMoveProduct : receiptMoveProductList) {
            receiptMoveProduct.setCuser(receiptMove.getCuser());
            receiptMoveProduct.setNumber(receiptMove.getNumber());
            //出库方
            Example exampleIn = new Example(CategoryProduct.class);
            Example.Criteria criteriaIn = exampleIn.createCriteria();
            criteriaIn.andEqualTo("categoryId", receiptMove.getOutCategory());
            criteriaIn.andEqualTo("productId", receiptMoveProduct.getProductId());
            List<CategoryProduct> categoryProductsOut = categoryProductMapper.selectByExample(exampleIn);
            for (CategoryProduct categoryProduct : categoryProductsOut) {
                try {
                    qwertyu(categoryProduct, receiptMoveProduct, false);
                    minusNum(categoryProduct, receiptMoveProduct);
                } catch (NumberFormatException e) {
                    log.error("金额格式错误");
                }
            }


            //入库方
            Example exampleOut = new Example(CategoryProduct.class);
            Example.Criteria criteriaOut = exampleOut.createCriteria();
            criteriaOut.andEqualTo("categoryId", receiptMove.getInCategory());
            criteriaOut.andEqualTo("productId", receiptMoveProduct.getProductId());
            List<CategoryProduct> categoryProductsIn = categoryProductMapper.selectByExample(exampleOut);
            //库里没这种物品新增，有了改数
            if (categoryProductsIn.size() == 0) {
                CategoryProduct categoryProduct = new CategoryProduct();
                qwertyu(categoryProduct, receiptMoveProduct, true);
                categoryProduct.setCategoryId(receiptMove.getInCategory());
                categoryProduct.setProductId(receiptMoveProduct.getProductId());
                categoryProduct.setProductNum(receiptMoveProduct.getNum());
                categoryProduct.setPrice(receiptMoveProduct.getPrice());
                categoryProduct.setTotalPrice(receiptMoveProduct.getTotalPrice());
                categoryProductMapper.insertSelective(categoryProduct);
            } else {
                for (CategoryProduct categoryProduct : categoryProductsIn) {
                    try {
                        qwertyu(categoryProduct, receiptMoveProduct, true);
                        addNum(categoryProduct, receiptMoveProduct);
                    } catch (NumberFormatException e) {
                        log.error("金额格式错误");
                    }
                }
            }
        }
        return entity;
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    public ReceiptMove view(String id) {
        ReceiptMove receiptMove = mapper.selectByPrimaryKey(id);
        receiptMove.setOutCategoryName(categoryMapper.selectByPrimaryKey(receiptMove.getOutCategory()).getName());
        receiptMove.setInCategoryName(categoryMapper.selectByPrimaryKey(receiptMove.getInCategory()).getName());
        if (StrUtil.isNotBlank(receiptMove.getConfirmUser())) {
            receiptMove.setConfirmUserName(userManagementMapper.selectByPrimaryKey(receiptMove.getConfirmUser()).getName());
        }
        receiptMove.setCuserName(userManagementMapper.selectByPrimaryKey(receiptMove.getCuser()).getName());
        Example example = new Example(ReceiptSetProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("receiptId", id);
        List<ReceiptMoveProduct> receiptMoveProductList = receiptMoveProductMapper.selectByExample(example);
        for (ReceiptMoveProduct receiptMoveProduct : receiptMoveProductList) {
            receiptMoveProduct.setProduct(productMapper.selectByPrimaryKey(receiptMoveProduct.getProductId()));
        }
        receiptMove.setReceiptMoveProductList(receiptMoveProductList);
        return receiptMove;
    }

    /**
     * 分页查询
     *
     * @param params
     * @return
     */
    public List<ReceiptMoveGetPageNew> getPages(PageParams<ReceiptMoveGetPageParams> params) {
        UserManagement user = userManagementMapper.selectByPrimaryKey(params.getParams().getUserId());
        if (user.getDataIsAll() == 1) {
            params.getParams().setIsAdmin(1);
        } else {
            params.getParams().setIsAdmin(2);
        }
        PageHelper.startPage(params.getCurrentPage(), params.getPerPageTotal());
        List<ReceiptMoveGetPageNew> pages = mapper.getPage(params.getParams());
        return pages;
    }

    public List<ReceiptMoveExtend> print(String ids) {
        List<ReceiptMoveExtend> list = mapper.selByIds(Arrays.asList(ids.split(",")));
        if (list != null && list.size() > 0) {
            for (ReceiptMoveExtend extend : list) {
                List<ReceiptMoveProductExtend> receiptMoveProductList = mapper.getReceiptMoveExtend(extend.getId());
                extend.setReceiptMoveProductList(receiptMoveProductList);
            }
        }
        return list;
    }

    public List<ReceiptMoveGetPage> export(ReceiptMoveGetPageParams params) {
        UserManagement user = userManagementMapper.selectByPrimaryKey(params.getUserId());
        if (user.getDataIsAll() == 1) {
            params.setIsAdmin(1);
        } else {
            params.setIsAdmin(2);
        }
//        List<ReceiptMoveGetPage> pages = mapper.getPages(params);
        List<ReceiptMoveGetPage> pages = mapper.export(params);
        for (ReceiptMoveGetPage receiptMoveGetPage : pages) {
            receiptMoveGetPage.setOutCategoryName(categoryMapper.selectByPrimaryKey(receiptMoveGetPage.getOutCategoryId()).getName());
            receiptMoveGetPage.setOutUserName(userManagementMapper.selectByPrimaryKey(receiptMoveGetPage.getOutUser()).getName());
            receiptMoveGetPage.setInCategoryName(categoryMapper.selectByPrimaryKey(receiptMoveGetPage.getInCategoryId()).getName());
            receiptMoveGetPage.setList(mapper.getPageExport(receiptMoveGetPage.getId()));
            if (StrUtil.isNotBlank(receiptMoveGetPage.getConfirmUser())) {
                receiptMoveGetPage.setConfirm1("已确认");
                receiptMoveGetPage.setConfirmUserName(userManagementMapper.selectByPrimaryKey(receiptMoveGetPage.getConfirmUser()).getName());
            } else {
                receiptMoveGetPage.setConfirm1("待确认");
            }
        }
        return pages;
    }
}
